package com.neusoft.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Scanner;

/*
 *	字节流：字节输入流（InputStream）和字节输出流（OutputStream）
 *  字符流：字符输入流（InputStream）和字符输出流（Writer）
 *       InputStreamInputStream和OutputStreamWriter是字节流通向字符流的桥梁，可以将字节流转成字符流
 *  
 *  序列化：关注于对象的序列化。
 *       对象在网络中或者跨介质存储中需要在传输之前将其转换为有序的字节序列；在传输到目标后，需要按照序列化的顺序进行组装；
 *       因为在传输的过程中，不能保证传输的顺序是按照预定的顺序到达目标位置的；
 *       transient:反序列化关键字；使用该关键字修饰的属性的值不会被进行序列化处理，在进行对象持久化信息读取时，
 *       会将反序列化的属性初始化为该属性类型的默认值
 *       
 *  对象流：使用序列化机制，将内存中某个时间节点的对象的状态信息持久化到一个文件中。
 *       所有使用对象流处理的类必须实现Serializable接口。
 *       该接口是一个空接口，也叫标识性接口，不需要实现任何方法，只需要implements该接口即可；
 *       注意：被对象输出流读取的持久化文件内容，要求必须是使用对象输出流输出的内容；
 *       使用对象输入流读入的对象是一个新的对象；
 *       
 *  总结：
 *     Java中用到的可以申请内存地址的方式：
 *     1.new申请并创建对象
 *     2.使用对象输入流复原一个对象（新分配内存地址，新对象）
 *     3.反射
 *       
 */
public class TestReaderAndWriter {
	public static void main(String[]args) {
		//test_ObjectOutputStream();
		System.out.println("==============");
		//test_ObjectInputStream();
		System.out.println("==============");
		//test_getContentFromConsoleByScanner();
		System.out.println("==============");
		//test_getContentFromConsole();
		test_BufferedInputAndOutputStreamer();
	}
	/**
	 * 使用对象输入流，将对象持久化的信息读取到内存中 注意：被读取的文件内容，要求必须是使用对象输出流输出的内容
	 */
	private static void test_ObjectInputStream() {
		//创建一个持久化对象的文件
		File file0=null;
		//创建一个对象输入流对象
		ObjectInputStream ooi=null;
		try {
			//创建一个持久化对象的文件
			file0=new File("G:/zcy2017/temp/obj_stu_02.dat");
			//创建一个对象输入流对象
			 ooi=new ObjectInputStream(new FileInputStream(file0));
			 
			 //将读取的对象内容还原为内存对象
			 Object obj=ooi.readObject();
			 Student stu0=(Student)obj;
			 System.out.println("创建学生的信息"+stu0.toString());
			 System.out.println("读文件完成");
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭资源
			try {
				if(ooi!=null) {
					ooi.close();
				}
			}catch(Exception e) {
				//异常信息
				System.out.println("关闭文件流资源出现异常："+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	/**
	 * 使用对象输出流，将对象持久化到文件中 
	 */
	private static void test_ObjectOutputStream() {
		//创建一个持久化对象的文件
		File file0=null;
		//创建一个对象输入流对象
		ObjectOutputStream oos=null;
		try {
			//创建一个持久化对象的文件
			file0=new File("G:/zcy2017/temp/obj_stu_02.dat");
			//创建一个对象输入流对象
			 oos=new ObjectOutputStream(new FileOutputStream(file0));
			 
			 //创建一个学生对象
			 Student stu0=new Student("林黛玉","0002",18,"女");
			 stu0.setStuAge(21);
			 System.out.println("创建的学生信息为："+stu0.toString());
			 //使用对象输出流，将当前的学生信息，持久化到文件中
			 oos.writeObject(stu0);
			 //清空缓存
			 oos.flush();
			 System.out.println("写文件完成");
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭资源
			try {
				if(oos!=null) {
					oos.close();
				}
			}catch(Exception e) {
				//异常信息
				System.out.println("关闭文件流资源出现异常："+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	/**
	 * 使用缓存流，读取从控制台输入的内容
	 */
	private static void test_getContentFromConsoleByScanner() {
		//创建一个带缓存功能的字符输入流的对象
		Scanner br=null;
		try {
			//创建一个缓存字节输入流类的对象
			br=new Scanner(System.in,"utf-8");
			System.out.println("请输入一串内容：");
			//读取控制台输入流内容
			//读取一行，以'\r''\n\结束的一行
			String strLine=br.nextLine();
			if(strLine!=null) {
				//将读取到的内容显示打印
				System.out.println(strLine);
			}
			//读取的是以空白字符结束的一部分内容，不一定是一行内容
			strLine=br.next();
			System.out.println("再次读取到的内容为："+strLine);
			
			strLine=br.next();
			System.out.println("再次读取到的内容为："+strLine);
			
			strLine=br.next();
			System.out.println("再次读取到的内容为："+strLine);
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭资源
			try {
				if(br!=null) {
					br.close();
				}
			}catch(Exception e) {
				//异常信息
				System.out.println("关闭文件流资源出现异常："+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	/**
	 * 使用缓存流，读取从控制台输入的内容
	 */
	private static void test_getContentFromConsole() {
		//创建一个带缓存功能的字符输入流的对象
		BufferedReader br=null;
		try {
			//创建一个缓存字节输入流类的对象
			br=new BufferedReader(new InputStreamReader(System.in,"utf-8"));
			System.out.println("请输入一串内容：");
			//读取控制台输入流内容
			//读取一行，以'\r''\n\结束的一行
			String strLine=br.readLine();
			if(strLine!=null) {
				//将读取到的内容显示打印
				System.out.println(strLine);
			}
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭资源
			try {
				if(br!=null) {
					br.close();
				}
			}catch(Exception e) {
				//异常信息
				System.out.println("关闭文件流资源出现异常："+e.getMessage());
				e.printStackTrace();
			}
		}
	}
	/**
	 * 缓存流的应用，使用输入流读取一个文件的内容，并使用输出流将输入流读取的内容写出到指定的输出文件中
	 */
	private static void test_BufferedInputAndOutputStreamer() {
		//创建一个带缓存功能的字符输入流类的对象
		BufferedReader br=null;
		//创建一个带缓存功能的字符输出流类的对象
		BufferedWriter bw=null;
		try {
			//创建输入流读取的文件对象
			File file0=new File("G:/zcy2017/temp/temp_file01.txt");
			//创建一个缓存字节输入流类的对象
			br=new BufferedReader(new InputStreamReader(new FileInputStream(file0),"utf-8"));
			//创建输出流的目标文件对象，输出流写出到的目标文件
			File file1=new File("G:/zcy2017/temp/temp_file01_out.txt");
			bw=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file1,true),"utf-8"));
			//可以使用printwriter进行多格式输出内容
			PrintWriter pw=new PrintWriter(file1);
			//读取存储的字节数组
			char[]bTemp=new char[1024];
			//读取存储的内容
			String strLine=br.readLine();
			while(strLine!=null) {
				//在文件的末尾写一个换行符
				bw.write("\n");
				//使用输出流将读取到的字节数组内容写出到输出流文件中
				bw.write(strLine);
				//将读取到的内容显示打印
				System.out.println(strLine);
			}
			//清空缓存区
			bw.flush();
			
			System.out.println("文件操作完成");
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//关闭资源
			try {
				if(br!=null) {
					br.close();
				}
				if(bw!=null) {
					br.close();
				}
			}catch(IOException e) {
				//异常信息
				System.out.println("关闭文件流资源出现异常："+e.getMessage());
				e.printStackTrace();
			}
		}
	}

}
